using System;
using System.Collections.Generic;
using Microsoft.DirectX.DirectInput;
using Microsoft.Xna.Framework.Input;
using System.Diagnostics;

namespace Soopah.Xna.Input
{
	/// <summary>
	/// The buttons on a PC Gamepad
	/// </summary>
	/// <remarks>
	/// The comparable X, Y, A, B etc are not currently mapped because the position of buttons
	/// indexed 0, 1, 2, etc varies widely from PC gamepad to PC gamepad
	/// Instead, you should provide an interface for the user to visually map the buttons on their
	/// gamepad to what you expect for X, Y, etc.
	/// Tools to support this mapping may be added to this framework in the future
	/// </remarks>
	public struct DirectInputButtons
	{
		
		public ButtonState X;
		public ButtonState Y;
		public ButtonState A;
		public ButtonState B;
		public ButtonState Back;
		public ButtonState Start;
		public ButtonState LeftShoulder;
		public ButtonState RightShoulder;
		public ButtonState LeftStick;
		public ButtonState RightStick;
        public DirectInputDPad DPad;
		

		public List<ButtonState> List;
        public List<Buttons> OnButtons;
		public DirectInputButtons(Device device)
		{
            try
            {
                byte[] buttons = device.CurrentJoystickState.GetButtons();
                OnButtons = new List<Buttons>();
                A = (buttons[0] == 0 ? ButtonState.Released : ButtonState.Pressed);
                B = (buttons[1] == 0 ? ButtonState.Released : ButtonState.Pressed);
                X = (buttons[2] == 0 ? ButtonState.Released : ButtonState.Pressed);
                Y = (buttons[3] == 0 ? ButtonState.Released : ButtonState.Pressed);
                LeftShoulder = (buttons[4] == 0 ? ButtonState.Released : ButtonState.Pressed);
                RightShoulder = (buttons[5] == 0 ? ButtonState.Released : ButtonState.Pressed);
                Back = (buttons[6] == 0 ? ButtonState.Released : ButtonState.Pressed);
                Start = (buttons[7] == 0 ? ButtonState.Released : ButtonState.Pressed);
                LeftStick = (buttons[8] == 0 ? ButtonState.Released : ButtonState.Pressed);
                RightStick = (buttons[9] == 0 ? ButtonState.Released : ButtonState.Pressed);
                JoystickState t = device.CurrentJoystickState;
                DPad = new DirectInputDPad(t.GetPointOfView()[0]);
                if (DPad.Left == ButtonState.Pressed)
                    OnButtons.Add(Buttons.DPadLeft);
                if (DPad.Right == ButtonState.Pressed)
                    OnButtons.Add(Buttons.DPadRight);
                if (DPad.Up == ButtonState.Pressed)
                    OnButtons.Add(Buttons.DPadUp);
                if (DPad.Down == ButtonState.Pressed)
                    OnButtons.Add(Buttons.DPadDown);

                int numButtons = device.Caps.NumberButtons;
                List = new List<ButtonState>(numButtons);

                for (int i = 0; i < numButtons; i++)
                {
                    List.Add((buttons[i] == 0 ? ButtonState.Released : ButtonState.Pressed));
                    if (buttons[i] != 0)
                    {
                        if (i == 0)
                            OnButtons.Add(Buttons.A);
                        else if (i == 1)
                            OnButtons.Add(Buttons.B);
                        else if (i == 2)
                            OnButtons.Add(Buttons.X);
                        else if (i == 3)
                            OnButtons.Add(Buttons.Y);
                        else if (i == 6)
                            OnButtons.Add(Buttons.Back);
                        else if (i == 7)
                            OnButtons.Add(Buttons.Start);
                        else if (i == 4)
                            OnButtons.Add(Buttons.LeftShoulder);
                        else if (i == 8)
                            OnButtons.Add(Buttons.LeftStick);
                        else if (i == 5)
                            OnButtons.Add(Buttons.RightShoulder);
                        else if (i == 9)
                            OnButtons.Add(Buttons.RightStick);
                    }
                }
            }
            catch (Exception ex)
            {
                Trace.WriteLine(ex.Message);
                Trace.WriteLine(ex.StackTrace);
                List = new List<ButtonState>(0);
                OnButtons = new List<Buttons>(0);
                A = 0;
                B = 0;
                X = 0;
                Y = 0;
                LeftShoulder = 0;
                RightShoulder = 0;
                LeftStick = 0;
                RightStick = 0;
                Start = 0; Back = 0;
                DPad = new DirectInputDPad(-1);
            }

		}

        public DirectInputButtons(Device device, ButtonSettings bSettings)
        {
            try
            {                
                byte[] buttons = device.CurrentJoystickState.GetButtons();
                OnButtons = new List<Buttons>();
                A = bSettings.AIndex >= 0 ? (buttons[bSettings.AIndex] == 0 ? ButtonState.Released : ButtonState.Pressed) : ButtonState.Released;
                B = bSettings.BIndex >= 0 ? (buttons[bSettings.BIndex] == 0 ? ButtonState.Released : ButtonState.Pressed) : ButtonState.Released;
                X = bSettings.XIndex >= 0 ? (buttons[bSettings.XIndex] == 0 ? ButtonState.Released : ButtonState.Pressed) : ButtonState.Released;
                Y = bSettings.YIndex >= 0 ? (buttons[bSettings.YIndex] == 0 ? ButtonState.Released : ButtonState.Pressed) : ButtonState.Released;
                LeftShoulder = bSettings.LBIndex >= 0 ? (buttons[bSettings.LBIndex] == 0 ? ButtonState.Released : ButtonState.Pressed) : ButtonState.Released;
                RightShoulder = bSettings.RBIndex >= 0 ? (buttons[bSettings.RBIndex] == 0 ? ButtonState.Released : ButtonState.Pressed) : ButtonState.Released;
                Back = bSettings.BackIndex >= 0 ? (buttons[bSettings.BackIndex] == 0 ? ButtonState.Released : ButtonState.Pressed) : ButtonState.Released;
                Start = bSettings.StartIndex >= 0 ? (buttons[bSettings.StartIndex] == 0 ? ButtonState.Released : ButtonState.Pressed) : ButtonState.Released;
                LeftStick = bSettings.LStickIndex >= 0 ? (buttons[bSettings.LStickIndex] == 0 ? ButtonState.Released : ButtonState.Pressed) : ButtonState.Released;
                RightStick = bSettings.RStickIndex >= 0 ? (buttons[bSettings.RStickIndex] == 0 ? ButtonState.Released : ButtonState.Pressed) : ButtonState.Released;
                JoystickState t = device.CurrentJoystickState;
                DPad = new DirectInputDPad(t.GetPointOfView()[0]);
                if (DPad.Left == ButtonState.Pressed)
                    OnButtons.Add(Buttons.DPadLeft);
                if (DPad.Right == ButtonState.Pressed)
                    OnButtons.Add(Buttons.DPadRight);
                if (DPad.Up == ButtonState.Pressed)
                    OnButtons.Add(Buttons.DPadUp);
                if (DPad.Down == ButtonState.Pressed)
                    OnButtons.Add(Buttons.DPadDown);

                int numButtons = device.Caps.NumberButtons;
                List = new List<ButtonState>(numButtons);
                

                for (int i = 0; i < numButtons; i++)
                {
                    List.Add((buttons[i] == 0 ? ButtonState.Released : ButtonState.Pressed));
                    if (buttons[i] != 0)
                    {
                        if (i == bSettings.AIndex)
                            OnButtons.Add(Buttons.A);
                        else if (i == bSettings.BIndex)
                            OnButtons.Add(Buttons.B);
                        else if (i == bSettings.XIndex)
                            OnButtons.Add(Buttons.X);
                        else if (i == bSettings.YIndex)
                            OnButtons.Add(Buttons.Y);
                        else if (i == bSettings.BackIndex)
                            OnButtons.Add(Buttons.Back);
                        else if (i == bSettings.StartIndex)
                            OnButtons.Add(Buttons.Start);
                        else if (i == bSettings.LBIndex)
                            OnButtons.Add(Buttons.LeftShoulder);
                        else if (i == bSettings.LStickIndex)
                            OnButtons.Add(Buttons.LeftStick);
                        else if (i == bSettings.RBIndex)
                            OnButtons.Add(Buttons.RightShoulder);
                        else if (i == bSettings.RStickIndex)
                            OnButtons.Add(Buttons.RightStick);
                    }
                }
            }
            catch (Exception ex)
            {
                Trace.WriteLine(ex.Message);
                Trace.WriteLine(ex.StackTrace);
                List = new List<ButtonState>(0);
                OnButtons = new List<Buttons>(0);
                A = 0;
                B = 0;
                X = 0;
                Y = 0;
                LeftShoulder = 0;
                RightShoulder = 0;
                LeftStick = 0;
                RightStick = 0;
                Start = 0; Back = 0;
                DPad = new DirectInputDPad(-1);
            }
        }
    }
}
